#ifndef RATIONAL_H_
#define RATIONAL_H_

#include <iostream>
#include <string>

class Rational
{
	public:
    
		Rational();
        Rational( int numerator, int denominator );
        Rational( int wholeNumber );
        Rational( const Rational &other );
        
        enum DisplayMode
        {
            // Display the fraction always in the format 'a/b', regardless
            // of whether a is greater than b or not.  If a == 0 or b == 1
            // then the fraction will simply be shown in the format 'a'
            Vulgar,
            
            // Display the fraction in the format a b/c where a == int(b/c),
            // if a == 0 then this output is identical to the Vulgar output.
            Mixed
        };
        
        void setDisplayMode( DisplayMode mode );
        DisplayMode displayMode() const;
        std::string toVulgarString() const;
        std::string toMixedString() const;
        
        int numerator;
        int denominator;
        
        Rational reduced() const;
        void reduce();
        
        Rational reciprocal() const;
        void reciprocate();
        
		static int gcd( int first, int second );
		static int lcm( int first, int second );
	
        bool operator ==( const Rational &other ) const;
        bool operator !=( const Rational &other ) const;
        bool operator >( const Rational &other ) const;
        bool operator <( const Rational &other ) const;
        bool operator >=( const Rational &other ) const;
        bool operator <=( const Rational &other ) const;
        
        Rational operator +( const Rational &other ) const;
        Rational operator -( const Rational &other ) const;
        Rational operator *( const Rational &other ) const;
        Rational operator /( const Rational &other ) const;
        
        Rational &operator +=( const Rational &other );
        Rational &operator -=( const Rational &other );
        Rational &operator *=( const Rational &other );
        Rational &operator /=( const Rational &other );
        
    private:
    
        void _equalizeDenominators( Rational &r1, Rational &r2 ) const;
        
        DisplayMode _displayMode;
};

std::ostream &operator <<( std::ostream &os, const Rational &r );


#endif /*RATIONAL_H_*/
